package member

import (
	"database/sql"
	"errors"
	"gpt-api/framework/codes"
	"gpt-api/framework/db"
	"gpt-api/framework/ginplus"
	"gpt-api/pkg/model"
	"gpt-api/pkg/response"
	"gpt-api/pkg/util"

	"github.com/gin-gonic/gin"
)

type Handler struct {
	db *db.DB
}

func New(db *db.DB) *Handler {
	return &Handler{db: db}
}

// 添加成员信息,有ID则更新
func (h *Handler) AddMember(c *gin.Context) error {
	userId := ginplus.GetUserID(c)
	var req struct {
		Username   string `json:"username" binding:"required,max=50"`
		Avatar     string `json:"avatar" binding:"max=255"`
		Gender     int    `json:"gender" binding:"oneof=0 1 2"`
		RelationId int    `json:"relation_id" binding:"gte=0"`
		Birthday   string `json:"birthday"`
		Birthplace string `json:"birthplace" binding:"max=150"`
		Diedday    string `json:"diedday"`
		Deathplace string `json:"deathplace" binding:"max=150"`
		MemberID   uint   `json:"member_id" binding:"gte=0"`
		Id         uint   `json:"id" binding:"gte=0"`
		Describe   string `json:"describe" binding:"max=255"`
		IsLiving   int    `json:"is_living" binding:"oneof=0 1"`
	}
	if err := c.Bind(&req); err != nil {
		return ginplus.ReplyBadRequest(c, err)
	}

	// 新增操作，根据关系ID查询是否唯一关系，并且查询是否已有唯一关系数据
	if req.MemberID == 0 && req.RelationId > 0 {
		relation, err := (&model.Relations{}).GetRelationsById(h.db, req.RelationId)
		if err != nil {
			return ginplus.ReplyInternalError(c, err)
		}

		// 如果是唯一关系，查询是否已有唯一关系数据
		if relation.OnlyOne == 1 {
			member, err := (&model.Member{}).GetMemberForRelationId(h.db, userId, []uint64{uint64(req.MemberID)}, []uint64{uint64(req.RelationId)})
			if err != nil {
				return ginplus.ReplyInternalError(c, err)
			}
			if len(member) > 0 {
				return ginplus.ReplyError(c, codes.MemberUniqueRelationshipAlreadyExists, nil)
			}
		}
	}

	// 如果MemberID有值查询成员信息是否存在
	if req.MemberID > 0 {
		member, err := (&model.Member{}).GetMemberById(h.db, uint64(req.MemberID))
		if err != nil {
			return ginplus.ReplyError(c, codes.MemberNotFound, nil)
		}
		if member.ID == 0 {
			return ginplus.ReplyError(c, codes.MemberNotFound, nil)
		}
		if member.UserID != uint(userId) {
			return ginplus.ReplyError(c, codes.MemberNotFound, nil)
		}
	}

	// 添加数据
	member := &model.Member{
		Username:   req.Username,
		Avatar:     req.Avatar,
		Gender:     req.Gender,
		Birthplace: req.Birthplace,
		Deathplace: req.Deathplace,
		MemberID:   req.MemberID,
		RelationID: req.RelationId,
		Describe:   req.Describe,
		UserID:     uint(userId),
		IsLiving:   req.IsLiving,
	}

	// 出生日期
	if req.Birthday != "" {
		member.Birthday = sql.NullTime{
			Time:  util.TimestampToTime(util.StrToTimestamp(req.Birthday)),
			Valid: true,
		}
	}
	// 去世日期
	if req.Diedday != "" {
		member.Diedday = sql.NullTime{
			Time:  util.TimestampToTime(util.StrToTimestamp(req.Diedday)),
			Valid: true,
		}
	}

	// 如果出生日期和死亡提起同时存在,判断时间差
	if member.Birthday.Valid && member.Diedday.Valid {
		birthday := member.Birthday.Time
		diedday := member.Diedday.Time
		if birthday.After(diedday) {
			return ginplus.ReplyError(c, codes.MemberBirthdayAfterDiedday, nil)
		}
	}

	// 如果健在,清除死亡信息
	if req.IsLiving == 1 {
		member.Diedday = sql.NullTime{}
		member.Deathplace = ""
	}

	// 如果传入ID，则更新
	if req.Id > 0 {
		member.ID = uint64(req.Id)
	}

	// 更新OR添加
	if err := member.AddOrUpdateMember(h.db, *member); err != nil {
		return ginplus.ReplyInternalError(c, err)
	}

	return ginplus.ReplyJSON(c, nil)
}

// 删除成员
func (h *Handler) DeleteMember(c *gin.Context) error {
	// 验证参数
	userId := ginplus.GetUserID(c)
	var req struct {
		Id uint `form:"id" binding:"required,gte=0"`
	}
	if err := c.Bind(&req); err != nil {
		return ginplus.ReplyBadRequest(c, err)
	}

	// 判断成员信息
	member, err := (&model.Member{}).GetMemberById(h.db, uint64(req.Id))
	if err != nil {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}
	if member.UserID != uint(userId) {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}

	// 查询是否存在下级成员
	children, err := (&model.Member{}).GetMemberChildren(h.db, uint64(req.Id))
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}
	if len(children) > 0 {
		// 拼接下级成员名称
		memberName := ""
		for _, v := range children {
			memberName += v.Username + ","
		}
		memberName = memberName[:len(memberName)-1]
		return ginplus.ReplyError(c, codes.MemberChildrenExist, errors.New("需先删除下级亲属："+memberName))
	}

	// 删除成员信息
	if err := member.DeleteMember(h.db, uint64(req.Id)); err != nil {
		return ginplus.ReplyInternalError(c, err)
	}
	return ginplus.ReplyJSON(c, nil)
}

// 获取成员详情
func (h *Handler) GetMember(c *gin.Context) error {
	// 验证参数
	userId := ginplus.GetUserID(c)
	var req struct {
		Id uint `form:"id" binding:"required,gte=0"`
	}
	if err := c.Bind(&req); err != nil {
		return ginplus.ReplyBadRequest(c, err)
	}

	// 成员信息
	member, err := (&model.Member{}).GetMemberById(h.db, uint64(req.Id))
	if err != nil {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}
	if member.UserID != uint(userId) {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}

	// 返回响应
	MemberInfo := &response.MemberInfoResp{
		ID:          member.ID,
		Username:    member.Username,
		Avatar:      member.Avatar,
		Gender:      member.Gender,
		Birthday:    "",
		Diedday:     "",
		Birthplace:  member.Birthplace,
		Deathplace:  member.Deathplace,
		MemberID:    uint64(member.MemberID),
		RelationID:  uint64(member.RelationID),
		EventCount:  uint64((&model.Events{}).GetEventCountByUserIdAndMemberId(h.db, userId, member.ID)),
		ImageCount:  uint64((&model.EventImage{}).CountEventImageByUserIdAndMemberId(h.db, userId, member.ID)),
		MemberCount: 0,
		Describe:    member.Describe,
		IsLiving:    member.IsLiving,
	}
	if member.Birthday.Valid {
		MemberInfo.Birthday = member.Birthday.Time.Format("2006-01-02 15:04:05")
	}
	if member.Diedday.Valid {
		MemberInfo.Diedday = member.Diedday.Time.Format("2006-01-02 15:04:05")
	}

	// 初始统计参数
	memberCount := 0
	var subMemberIds, parentMemberIds []uint64

	// 统计直属一级成员数量
	subOneChile, err := (&model.Member{}).GetMemberChildrenByUserIdAndMemberIds(h.db, userId, []uint64{uint64(member.ID)})
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}
	memberCount += len(subOneChile)

	// 统计直属二级成员数量
	for _, v := range subOneChile {
		subMemberIds = append(subMemberIds, v.ID)
	}
	subTwoChile, err := (&model.Member{}).GetMemberChildrenByUserIdAndMemberIds(h.db, userId, subMemberIds)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}
	memberCount += len(subTwoChile)

	// 查询一级父级成员
	parentMemberIds = append(parentMemberIds, uint64(member.MemberID))
	parentOneMembers, err := (&model.Member{}).GetMembersByIds(h.db, parentMemberIds)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}
	for _, v := range parentOneMembers {
		parentMemberIds = append(parentMemberIds, uint64(v.MemberID))
	}

	// 统计全部父级成员
	parentMembers, err := (&model.Member{}).GetMembersByIds(h.db, parentMemberIds)
	if err != nil {
		return ginplus.ReplyInternalError(c, err)
	}
	memberCount += len(parentMembers)

	// 成员数据
	MemberInfo.MemberCount = uint64(memberCount)

	return ginplus.ReplyJSON(c, MemberInfo)
}

// 获取用户全部成员列表
func (h *Handler) ListMembers(c *gin.Context) error {
	// 验证参数
	userId := ginplus.GetUserID(c)

	// 查询全部成员
	members, err := (&model.Member{}).GetMemberChildrenByUserId(h.db, userId)
	if err != nil {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}

	// 遍历成员
	var MemberList []*response.MemberListResp
	for _, member := range members {
		item := &response.MemberListResp{
			ID:       member.ID,
			Username: member.Username,
			Avatar:   member.Avatar,
			Gender:   member.Gender,
			Birthday: "",
			Diedday:  "",
			Child:    nil,
			MemberId: uint64(member.MemberID),
			IsLiving: member.IsLiving,
			Relations: response.MemberListRelationsResp{
				Id:   uint64(member.RelationID),
				Name: member.Relation.Name,
			},
		}
		if member.Birthday.Valid {
			item.Birthday = member.Birthday.Time.Format("2006-01-02 15:04:05")
		}
		if member.Diedday.Valid {
			item.Diedday = member.Diedday.Time.Format("2006-01-02 15:04:05")
		}
		MemberList = append(MemberList, item)
	}

	// 生成树状结构数据
	MemberTree := TreeMembers(MemberList, 0)

	return ginplus.ReplyJSON(c, MemberTree)
}

// 生成成员列表树状结构
func TreeMembers(member []*response.MemberListResp, parentId uint64) []*response.MemberListResp {
	res := make([]*response.MemberListResp, 0)

	// 遍历数据
	for _, v := range member {
		if v.MemberId == parentId {
			v.Child = TreeMembers(member, v.ID)
			res = append(res, v)
		}
	}
	return res
}

// 获取用户全部成员列表-平铺
func (h *Handler) ListMembersAll(c *gin.Context) error {
	// 验证参数
	userId := ginplus.GetUserID(c)

	// 查询全部成员
	members, err := (&model.Member{}).GetMemberChildrenByUserId(h.db, userId)
	if err != nil {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}

	// 遍历成员
	var MemberList []*response.MemberListResp
	for _, member := range members {
		item := &response.MemberListResp{
			ID:       member.ID,
			Username: member.Username,
			Avatar:   member.Avatar,
			Gender:   member.Gender,
			Birthday: "",
			Diedday:  "",
			Child:    nil,
			MemberId: uint64(member.MemberID),
			IsLiving: member.IsLiving,
			Relations: response.MemberListRelationsResp{
				Id:   uint64(member.RelationID),
				Name: member.Relation.Name,
			},
		}
		if member.Birthday.Valid {
			item.Birthday = member.Birthday.Time.Format("2006-01-02 15:04:05")
		}
		if member.Diedday.Valid {
			item.Diedday = member.Diedday.Time.Format("2006-01-02 15:04:05")
		}
		MemberList = append(MemberList, item)
	}

	return ginplus.ReplyJSON(c, MemberList)
}

// 根据成员ID获取直属成员
func (h *Handler) ListMemberChild(c *gin.Context) error {
	// 验证参数
	userId := ginplus.GetUserID(c)
	var req struct {
		Id uint `form:"id" binding:"required,gte=0"`
	}
	if err := c.Bind(&req); err != nil {
		return ginplus.ReplyBadRequest(c, err)
	}

	// 成员信息
	member, err := (&model.Member{}).GetMemberById(h.db, uint64(req.Id))
	if err != nil {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}
	if member.UserID != uint(userId) {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}

	// 初始化参数
	var parentIds, subIds []uint64
	var MemberList []*response.MemberListResp

	// 查询一级子集成员
	subOneMembers, err := (&model.Member{}).GetMemberChildrenByUserIdAndMemberIds(h.db, userId, []uint64{uint64(req.Id)})
	if err != nil {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}
	for _, member := range subOneMembers {
		item := &response.MemberListResp{
			ID:       member.ID,
			Username: member.Username,
			Avatar:   member.Avatar,
			Gender:   member.Gender,
			MemberId: uint64(member.MemberID),
			Relations: response.MemberListRelationsResp{
				Id:   uint64(member.RelationID),
				Name: member.Relation.Name,
			},
		}
		MemberList = append(MemberList, item)

		// 一级子集成员ID
		subIds = append(subIds, uint64(member.ID))
	}

	// 查询二级子集成员
	subTwoMembers, err := (&model.Member{}).GetMemberChildrenByUserIdAndMemberIds(h.db, userId, subIds)
	if err != nil {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}
	for _, member := range subTwoMembers {
		item := &response.MemberListResp{
			ID:        member.ID,
			Username:  member.Username,
			Avatar:    member.Avatar,
			Gender:    member.Gender,
			MemberId:  uint64(member.MemberID),
			Relations: response.MemberListRelationsResp{},
		}
		MemberList = append(MemberList, item)
	}

	// 查询一级父级成员
	parentIds = append(parentIds, uint64(member.MemberID))
	parentOneMembers, err := (&model.Member{}).GetMembersByIds(h.db, parentIds)
	if err != nil {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}
	for _, member := range parentOneMembers {
		// 一级父级成员ID
		parentIds = append(parentIds, uint64(member.MemberID))
	}

	// 查询所有父级成员
	parentTwoMembers, err := (&model.Member{}).GetMembersByIds(h.db, parentIds)
	if err != nil {
		return ginplus.ReplyError(c, codes.MemberNotFound, nil)
	}

	// 遍历数据
	for _, parentTwoMember := range parentTwoMembers {
		item := &response.MemberListResp{
			ID:        parentTwoMember.ID,
			Username:  parentTwoMember.Username,
			Avatar:    parentTwoMember.Avatar,
			Gender:    parentTwoMember.Gender,
			MemberId:  uint64(parentTwoMember.MemberID),
			Relations: response.MemberListRelationsResp{},
		}
		MemberList = append(MemberList, item)
	}

	return ginplus.ReplyJSON(c, MemberList)
}
